<?php

namespace app\api\service;

use app\common\Common;
use app\model\Applet;
use app\model\User;
use app\model\UserWechatSubscribeConfig;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\helper\Arr;

class WechatSubscribeService
{
    //类型
    const TYPE_SIGN_REMIND = 'sign_remind';//签到提醒
    const TYPE_VIDEO_UPDATE = 'video_update';//剧集更新
    const TYPE_NEW_VIDEO_ONLINE = 'new_video_online';//新视频上线

    const TYPE_SIGN_REMIND_TID = '45056';
    const TYPE_VIDEO_UPDATE_TID = '44911';
    const TYPE_NEW_VIDEO_ONLINE_TID = '12212';

    const TYPE_TID_MAP = [
        self::TYPE_SIGN_REMIND => self::TYPE_SIGN_REMIND_TID,
        self::TYPE_VIDEO_UPDATE => self::TYPE_VIDEO_UPDATE_TID,
        self::TYPE_NEW_VIDEO_ONLINE => self::TYPE_NEW_VIDEO_ONLINE_TID,
    ];

    /**
     * 操作发送
     * @param $data
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function doSend($data): bool
    {
        try {
            $type = $data['type'] ?? self::TYPE_VIDEO_UPDATE;
            $page = $data['page'] ?? '';
            $params = [];
            switch ($type){
                //签到提醒
                case self::TYPE_SIGN_REMIND:
                    {
                        $params = [
                            'thing4' => ['value' => '第{day}天签到可获得 {kb} K币'],
                            'thing5' => ['value' => '签到领K币，解锁精彩剧集'],
                            'thing6' => ['value' => '每人每天只能签到一次'],
                        ];
                    }
                    break;
                //剧集更新
                case self::TYPE_VIDEO_UPDATE:
                    {
                        $params = [
                            'thing1' => ['value' => $data['thing1']],
                            'thing2' => ['value' => $data['thing2']],
                            'time3' => ['value' => $data['time3']],
                            'thing4' => ['value' => $data['thing4']],
                        ];
                    }
                    break;
                //新视频上线
                case self::TYPE_NEW_VIDEO_ONLINE:
                    {
                        $params = [
                            'thing1' => ['value' => $data['thing1']],
                            'thing2' => ['value' => $data['thing2']],
                            'time3' => ['value' => $data['time3']],
                        ];
                    }
                    break;
            }
            if ($params){
                $thing4Value = $params['thing4']['value'] ?? '';
                Applet::whereNotNull('wechat_subscribe_template')->chunk(1000,function ($items) use($type,$params,$page,$thing4Value){
                    foreach ($items as $item){
                        $wechatSubscribeTemplate = $item->wechat_subscribe_template ?? [];
                        if ($wechatSubscribeTemplate){
                            foreach ($wechatSubscribeTemplate as $subTmp){
                                $tmplId = $subTmp['tmplId'];
                                $tid = $subTmp['tid'];
                                $sendTid = Arr::get(self::TYPE_TID_MAP,$type,null);
                                if ($tid == $sendTid){
                                    $userTmplConfig = UserWechatSubscribeConfig::where('applet_id',$item->id)->select();
                                    if (!$userTmplConfig->isEmpty()){
                                        foreach ($userTmplConfig as $subConfig){
                                            $exists = self::checkUserTemplateOn($subConfig->user_id,$subConfig->applet_id,$tmplId);
                                            if ($exists){
                                                if ($type == self::TYPE_SIGN_REMIND){
                                                    [$money,$signDay] = self::getSignInfo($subConfig->user);
                                                    $tmpStr = str_replace('{day}',$signDay,$thing4Value);
                                                    $tmpStr = str_replace('{kb}',$money,$tmpStr);
                                                    $params['thing4']['value'] = $tmpStr;
                                                }
                                                self::sendMessage($item,$subConfig->user,$tmplId,$params,$page);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                },'id','DESC');
            }
            return true;
        }catch (\Throwable $e){
            flog([
                'message' => '微信订阅消息发送失败',
                'data' => $data,
                'error' => $e->getFile().'--'.$e->getLine().'--'.$e->getMessage(),
            ],'wechat_subscribe_send','error');
            return false;
        }
    }

    /**
     * 发送订阅消息
     * @param Applet $applet
     * @param User $user
     * @param $templateId
     * @param $data
     * @param $page
     * @return bool
     */
    public static function sendMessage(Applet $applet,User $user,$templateId,$data,$page): bool
    {
        $uri = '/cgi-bin/message/subscribe/send';
        // 获取微信accessToken
        $accessToken = Common::getWechatAppletStableAccessToken($applet->app_id, $applet->app_secret, $applet->id);
        // 调用第三方请求参数
        $postBody =  json_encode([
            'access_token' => $accessToken,
            'template_id' => $templateId,
            'page' => $page,
            'touser' => $user->open_id,
            'data' => $data,
            'miniprogram_state' => config('app.env') == 'sandbox' ? 'trial' : 'formal',
            'lang' => 'zh_CN',
        ]);
        flog([
            'message' => '微信订阅消息发送参数',
            'postBody' => $postBody,
        ],'wechat_subscribe_send');
        $requestUrl = config('enum.wechat_pay_base_url').$uri.'?access_token='.$accessToken;
        $result = Common::curlRequest($requestUrl, 'POST', $postBody);
        $res = json_decode($result, true);
        flog([
            'message' => '微信订阅消息发送结果',
            'res' => $res,
        ],'wechat_subscribe_send');
        $errcode = Arr::get($res,'errcode',-1);
        return $errcode == 0;
    }

    /**
     * 检查用户模版是否打开
     * @param $userId
     * @param $appletId
     * @param $templateId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function checkUserTemplateOn($userId,$appletId,$templateId): bool
    {
        $info = UserWechatSubscribeConfig::where([
            'user_id' => $userId,
            'applet_id' => $appletId
        ])->find();
        if ($info){
            $subscribeConfig = $info->subscribe_config ?? [];
            if ($subscribeConfig){
                foreach ($subscribeConfig as $item){
                    if (isset($item['template_id']) && $item['template_id'] == $templateId && $item['status'] == UserWechatSubscribeConfig::STATUS_ON){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 获取签到信息
     * @param $user
     * @return int[]
     */
    public static function getSignInfo($user): array
    {
        $money = 0;
        $signDay = 0;
        // 连续签到
        if ($user->sign_day == 0 || $user->sign_day == 7) {
            // 第1天签到或者签到已满7天
            $money = 35;
            $signDay = 1;
        } else if ($user->sign_day == 1) {
            // 连续第2天签到
            $money = 40;
            $signDay = 2;
        } else if ($user->sign_day == 2) {
            // 连续第3天签到
            $money = 45;
            $signDay = 3;
        } else if ($user->sign_day == 3) {
            // 连续第4天签到
            $money = 50;
            $signDay = 4;
        } else if ($user->sign_day == 4) {
            // 连续第5天签到
            $money = 55;
            $signDay = 5;
        } else if ($user->sign_day == 5) {
            // 连续第6天签到
            $money = 60;
            $signDay = 6;
        } else if ($user->sign_day == 6) {
            // 连续第7天签到
            $money = 70;
            $signDay = 7;
        }
        return [$money,$signDay];
    }
}